/**
 * @Project: LizhiFM
 * @Author: wzsam
 * @Date: Oct 24, 2013
 * @Copyright: (c) 2013 广州市一把伞网络科技有限公司 All rights reserved.
 */

package com.hubujun.driverlicense.util;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;

import android.app.ActivityManager;
import android.content.Context;
import android.os.Environment;
import android.os.StatFs;


public class FileUtils {
	// 创建文件
	public static File createFile(String fileName) throws IOException {
		File file = new File(fileName);
		if (!file.exists()) {
			file.createNewFile();
		}
		return file;
	}

	// 删除文件
	public static void deleteFile(String fileName) throws IOException {
		File file = new File(fileName);
		if (file.exists()) {
			file.delete();
		}
	}

	// 创建目录
	public static File createDir(String fileName) {
		File dir = new File(fileName);
		try {
			if (!dir.exists()) {
				dir.mkdirs();
			}
		} catch (Exception ex) {
		}
		return dir;
	}

	// 判断文件是否存在
	public static boolean isExist(String fileName) {
		if(TextUtils.isNullOrEmpty(fileName)){
			return false;
		}

		File file = new File(fileName);
		return file.exists();
	}

	public static void copyDir(final File srcDir, final File destDir, final List<String> ignoreFiles) {
		if (!srcDir.exists()) {
			return;
		} else {
			if (!srcDir.isDirectory()) {
				return;
			}
		}
		if (destDir.exists()) {
			if (!destDir.isDirectory()) {
				return;
			}
		} else {
			if (!destDir.mkdirs()) {
				return;
			}
		}
		FileFilter filter = null;
		if (ignoreFiles.size() > 0) {
			filter = new FileFilter() {

				@Override
				public boolean accept(File pathname) {
					Ln.e("luoying copyDir fileter accept pathname = %s", pathname);
					int index = -1;
					for (int i = 0; i < ignoreFiles.size(); i++) {
						if (pathname.equals(ignoreFiles.get(i))) {
							index = i;
							break;
						}
					}
					if (index >= 0) {
						ignoreFiles.remove(index);
						return false;
					}
					return true;
				}
			};
		}
		File[] files = srcDir.listFiles(filter);
		for (File file : files) {
			Ln.e("luoying copyDir fileter accept file = %s", file);
			if (file.isDirectory()) {
				copyDir(file, new File(destDir, file.getName()), ignoreFiles);
			} else {
				copy(file, new File(destDir, file.getName()));
			}
		}
	}

	/**
	 * 获取 文件夹下所有的文件大小
	 * 
	 * @return * kb
	 */
	public static long getSize(String filePath) {
		File file = new File(filePath);
		if (!file.exists()) {
			return 0;
		}
		return getSize(file);
	}

	/**
	 * 获取文件后缀名
	 * @param fileName
	 * @return
	 */
	public static String getFileExtension(String fileName) {
		int index = fileName.lastIndexOf('.');
		if (index > 0) {
			String e = fileName.substring(index);
			return e.toLowerCase();
		}
		return "";
	}

	/**
	 * 根据后缀名 创建文件筛选器
	 * @param extensions
	 * @return
	 */
	public static FileFilter getFileFilterByExtensions(final List<String> extensions){
		FileFilter fileFilter = null;
		fileFilter =  new FileFilter() {
			@Override
			public boolean accept(File file) {
				if (file.isDirectory()) {
					return true;
				} else if (file.isFile()) {
					return extensions.contains(FileUtils.getFileExtension(file.getName()));
				}
				return false;
			}
		};

		return fileFilter;
	}

	/**
	 * 获取 文件夹下所有的文件大小
	 * 
	 * @param file
	 * @return * B(byte)
	 */
	public static long getSize(File file) {
		// 判断文件是否存在
		if (file.exists()) {
			// 如果是目录则递归计算其内容的总大小，如果是文件则直接返回其大小
			if (!file.isFile()) {
				// 获取文件大小
				File[] fl = file.listFiles();
				long ss = 0;
				if (fl == null) {
					return ss;
				}
				for (File f : fl)
					ss += getSize(f);
				return ss;
			} else {
				return file.length();
			}
		} else {
			return 0;
		}
	}

	/**
	 * 删除文件夹下的所有文件及文件夹
	 * 
	 * @param absfolderpath
	 */
	public static void delFolder(String absfolderpath) {
		try {
			delAllFile(absfolderpath);
			File path = new File(absfolderpath);
			path.delete();
		} catch (Exception e) {
			Ln.e(e);
		}
	}

	public static boolean delAllFile(String abspath, String[] ignoreFiles) {
		boolean flag = false;
		File file = new File(abspath);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}

		File tmpfile = null;
		for (String filename : file.list()) {
			tmpfile = new File(file, filename);
			int index = Arrays.binarySearch(ignoreFiles, tmpfile.getAbsolutePath());
			Ln.e("tmpfile = %s", tmpfile.getAbsolutePath(), index);
			if (index >= 0) {
				continue;
			}
			if (tmpfile.isFile()) {
				boolean success = tmpfile.delete();
				Ln.e("delAllFile delete %s file success ? %s", tmpfile.getAbsolutePath(), success);
			}
			if (tmpfile.isDirectory()) {
				delAllFile(file.getAbsolutePath() + "/" + filename + "/", ignoreFiles);
				tmpfile.delete();
				flag = true;
			}
		}
		return flag;
	}

	/**
	 * 根据绝对路径删除文件
	 * 
	 * @param abspath
	 * @return
	 */
	public static boolean delAllFile(String abspath) {
		boolean flag = false;
		File file = new File(abspath);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}

		File tmpfile = null;
		for (String filename : file.list()) {
			tmpfile = new File(file, filename);
			if (tmpfile.isFile()) {
				boolean success = tmpfile.delete();
				if (success == false) {
					Ln.e("delete file fail");
				}
			}
			if (tmpfile.isDirectory()) {
				delAllFile(file.getAbsolutePath() + "/" + filename + "/");
				delFolder(file.getAbsolutePath() + "/" + filename);
				flag = true;
			}
		}
		return flag;
	}

	public static boolean Move(String srcFile, String destPath) {
		File file = new File(srcFile);
		return file.renameTo(new File(new File(destPath), file.getName()));
	}

	public static void Copy(String oldPath, String newPath) {
		copy(new File(oldPath), new File(newPath));
	}

	public static void copy(File oldFile, File newFile) {
		try {
			int byteread = 0;
			if (oldFile.exists()) {
				if (newFile.exists()) {
					newFile.delete();
				}
				newFile.createNewFile();

				InputStream inStream = new FileInputStream(oldFile);
				FileOutputStream fs = new FileOutputStream(newFile);
				byte[] buffer = new byte[1444];
				while ((byteread = inStream.read(buffer)) != -1) {
					fs.write(buffer, 0, byteread);
				}
				fs.flush();
				inStream.close();
				fs.close();
			}
		} catch (Exception e) {
			Ln.e(e);
		}
	}

	/**
	 * 判断是否有sd卡
	 * 
	 * @return
	 */
	public static boolean hasSDCard() {
		return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
	}

	/**
	 * 检查存储卡剩余容量
	 */
	public static long getAvailableSDCardStore() {
		if (hasSDCard()) {
			StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getPath());
			long blocks = statFs.getAvailableBlocks();
			long blockSize = statFs.getBlockSize();
			return blocks * blockSize / 1024 / 1024;
		} else{
			return 0L;
		}
	}



	private static  long getCurrentPathAvilableSize(String path){
		if(TextUtils.isNullOrEmpty(path)){
			return  0l;
		}

		StatFs statFs = new StatFs(path);
		long blocks = statFs.getAvailableBlocks();
		long blockSize = statFs.getBlockSize();
		return blocks * blockSize / 1024 / 1024;
	}





	/**
	 * 获取sd卡总大小
	 * 
	 * @param context
	 * @return
	 */
	public static long getSDTotalSize(Context context) {
		File path = Environment.getExternalStorageDirectory();
		StatFs stat = new StatFs(path.getPath());
		long blockSize = stat.getBlockSize();
		long totalBlocks = stat.getBlockCount();
		return blockSize * totalBlocks / 1024;
	}

	/**
	 * 获得可用内存大小(兆)
	 * 
	 * @param mContext
	 * @return
	 */
	public static long getAvailableMemStore(Context mContext) {
		long MEM_UNUSED;
		ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);

		ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
		am.getMemoryInfo(mi);
		MEM_UNUSED = mi.availMem;
		return MEM_UNUSED;
	}

	public static void inputStreamToFile(InputStream is, File file) {
		try {
			OutputStream os = new FileOutputStream(file);
			int bytesRead = 0;
			byte[] buffer = new byte[8192];
			while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
				os.write(buffer, 0, bytesRead);
			}
			os.close();
			is.close();
		} catch (Exception e) {
			Ln.e(e);
		}
	}

	public static String formatSpeed(float speed) {
		if (speed < 1024) {
			return ((int) speed) + " B/s";
		} else if (speed < 1024 * 1024) {
			return ((int) (speed / 1024)) + " KB/s";
		} else {
			return ((int) (speed / 1024 / 1024)) + " MB/s";
		}
	}


}
